import 'package:flutter/material.dart';
import 'package:flutter_yfree/YFree.dart';

void showRightSheet({
  required BuildContext context,
  required Widget child,
  Function(RightSheetController controller)? onCreate,
  Color? bgColor,
  Duration? animation,
  bool? enableDrag,
  bool? isDismissible,
}) {
  late OverlayEntry overlay;
  overlay = OverlayEntry(
    builder: (context) {
      return _RightSheet(
        onPop: () {
          try {
            overlay.remove();
          } catch (e) {}
        },
        bgColor: bgColor ?? Colors.black.withAlpha(50),
        animation: animation ?? const Duration(milliseconds: 200),
        isDismissible: isDismissible ?? true,
        onCreate: onCreate,
        child: child,
      );
    },
  );
  Overlay.of(context).insert(overlay);
}

class RightSheetController {
  RightSheetController(this.state);

  _RightSheetState state;

  void dismiss() {
    state._controller.reverse();
    Future.delayed(state.widget.animation, () => state.widget.onPop());
  }
}

class _RightSheet extends StatefulWidget {
  _RightSheet({
    required this.child,
    required this.bgColor,
    required this.onPop,
    required this.animation,
    required this.isDismissible,
    required this.onCreate,
  });

  Widget child;
  Color bgColor;
  Duration animation;
  Function() onPop;
  bool isDismissible;
  Function(RightSheetController controller)? onCreate;

  @override
  _RightSheetState createState() => _RightSheetState();
}

class _RightSheetState extends State<_RightSheet> with SingleTickerProviderStateMixin {
  late double contentWidth;
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    widget.onCreate?.call(RightSheetController(this));
    contentWidth = yScreenSize().width;
    _controller = AnimationController(
      vsync: this,
      duration: widget.animation,
      reverseDuration: widget.animation,
      lowerBound: 0,
      upperBound: contentWidth,
    );
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.transparent,
      body: GestureDetector(
        onTap: () {
          if (!widget.isDismissible) return;
          _controller.reverse();
          Future.delayed(widget.animation, () => widget.onPop());
        },
        child: TweenAnimationBuilder<double>(
          tween: Tween(begin: 0, end: 1),
          duration: widget.animation,
          builder: (context, value, child) {
            return Opacity(
              opacity: value,
              child: Container(
                width: yScreenSize().width,
                height: yScreenSize().height,
                color: widget.bgColor,
                alignment: Alignment.bottomCenter,
                child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, child) {
                    return Transform.translate(
                      offset: Offset(contentWidth - _controller.value, 0),
                      child: GestureDetector(
                        onTap: () {},
                        child: Container(
                          width: yScreenSize().width,
                          constraints: BoxConstraints(maxHeight: yScreenSize().height),
                          child: widget.child,
                        ),
                      ),
                    );
                  },
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}
